package com.amtf.datafile2.core.excel;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import com.amtf.datafile2.DataAccessor;
import com.amtf.datafile2.DataException;
import com.amtf.datafile2.cfg.excel.ExcelDataFieldDefinition;
import com.amtf.datafile2.cfg.excel.ExcelDataTableDefinition;
import com.amtf.utils.FileUtils;

public class ExcelDataAccessor implements DataAccessor<ExcelDataCatalog, ExcelDataTable, ExcelDataTableDefinition, ExcelDataFieldDefinition> {
	private File file = null;
	private File copyForReadWrite = null;

	private Workbook workbook = null;
	private ExcelDataCatalog workDataCatalog = null;

	// private ExcelDataRecordDefinition definition = null;

	// public ExcelDataAccessor(File file) throws IOException {
	// this(file, ExcelDataRecordDefinitionStore.DEFAULT_EXCEL_DEFINITION.clone());
	// }

	public ExcelDataAccessor(File file) {
		this.file = file;
	}

	public ExcelDataCatalog open() throws DataException {
		if (file.exists() && file.length() != 0) {
			try {

				// copyForReadWrite = File.createTempFile("~" + file.getName(), ".tmp");
				copyForReadWrite = File.createTempFile("~EX", ".tmp");
				FileUtils.copyFile(file, copyForReadWrite);
				workbook = WorkbookFactory.create(copyForReadWrite);
			} catch (Exception e) {
				e.printStackTrace();
				throw new DataException(e);
			}
		} else {
			if (file.getName().toLowerCase().contains(".xlsx")) {
				workbook = new SXSSFWorkbook();
			} else {
				workbook = new HSSFWorkbook();
			}
		}

		workDataCatalog = new ExcelDataCatalog(file.getName(), workbook);
		return workDataCatalog;
	}

	public void commit() throws DataException {
		if (file != null && workDataCatalog != null) {
			try {
				OutputStream out = new FileOutputStream(file);
				workDataCatalog.getWorkbook().write(out);
				out.close();
			} catch (Throwable e) {
				e.printStackTrace();
				throw new DataException(e);
			}
		}
	}

	public void close() throws DataException {
		workDataCatalog.close();
		workDataCatalog = null;

		if (copyForReadWrite != null) {
			if (!copyForReadWrite.delete()) {
				try {
					// Delete the file
					new FileOutputStream(copyForReadWrite).close();
				} catch (Throwable e) {
					e.printStackTrace();
					throw new DataException(e);
				}
				copyForReadWrite.deleteOnExit();
			}
		}

		file = null;
		copyForReadWrite = null;
		workbook = null;
	}

}
